package Core 
{
	import com.junkbyte.console.Cc;
	import Common.Preloader;
	import flash.display.Bitmap;
	import flash.display.Loader;
	import flash.display.LoaderInfo;
	import flash.display.MovieClip;
	import flash.display.Shape;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.geom.Matrix;
	import flash.net.URLRequest;
	
	/**
	 * ...
	 * @author Serg de Adelantado
	 */
	public class ImageViewer extends Sprite 
	{
		private var FBitmap:Bitmap;
		private var FOriginalSize:Point;
		private var FScaledSize:Point;
		private var FFullsize:Boolean;
		private var FWidth:Number;
		private var FHeight:Number;
		private var FMaxSize:Number;
		private var FRotation:int;
		private var FPreloader:MovieClip;
		private var FRemoteLoader:Loader;
		
		public function ImageViewer() 
		{
			useHandCursor = true;
			buttonMode = true;			
			FOriginalSize = new Point();
			FScaledSize = new Point();
			FWidth = new Number(width);
			FHeight = new Number(height);			
			FWidth < FHeight ? FMaxSize = FWidth : FMaxSize = FHeight;			
			FPreloader = new Preloader();
			FPreloader.visible = false;
			FPreloader.stop();
			addChild(FPreloader);
			FRemoteLoader = new Loader();			
			addEventListener(MouseEvent.MOUSE_DOWN, OnMouseDown);
		}
		
		private function OnMouseDown(e:MouseEvent):void 
		{
			visible = false;
		}
		
		public function set Image(AImage:ImageContainer):void
		{
			Close();			
			if (AImage.Photo)
			{				
				visible = true;
				FPreloader.visible = true;
				FPreloader.play();
				FRotation = AImage.Rotation;
				if (AImage is LocalImage)				
					LoadLocal(LocalImage(AImage))
				else				
					LoadRemote(RemoteImage(AImage));				
			}
		}
		
		private function LoadLocal(AImage:LocalImage):void 
		{			
			AImage.File.addEventListener(Event.COMPLETE, OnLocalFileLoaded);
			AImage.File.load();				
			Cc.logch('Viewer', 'Loading local: ' + AImage.File.name);
		}
		
		private function LoadRemote(AImage:RemoteImage):void 
		{
			FRemoteLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, OnImageLoaded);
			FRemoteLoader.load(new URLRequest(AImage.BigImageURL));
			Cc.logch('Viewer', 'Loading remote: ' + AImage.BigImageURL);
		}
		
		private function OnLocalFileLoaded(e:Event):void
		{
			e.target.removeEventListener(Event.COMPLETE, OnLocalFileLoaded);
			var vLoader:Loader = new Loader();
			vLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, OnImageLoaded);
			vLoader.loadBytes(e.target.data);
		}
		
		private function OnImageLoaded(e:Event):void 
		{
			e.target.removeEventListener(Event.COMPLETE, OnImageLoaded);			
			FBitmap = Bitmap(e.target.content);
			FBitmap.smoothing = true;
			
			FOriginalSize.x = FBitmap.width;
			FOriginalSize.y = FBitmap.height;
			
			FitToScreen();			
			Rotation = FRotation;	
			FPreloader.visible = false;
			FPreloader.stop();
			addChild(FBitmap);
			
			LoaderInfo(e.target).bytes.clear();
			if (LoaderInfo(e.target).loader)			
				LoaderInfo(e.target).loader.unloadAndStop();				
		}
		
		private function FitToScreen():void
		{
			if (FBitmap)
			{
				if (Math.abs(FRotation) == 90 || Math.abs(FRotation) == 270)
					ImageUtils.Resize(FBitmap, FMaxSize - 10, FMaxSize - 10);
				else
					ImageUtils.Resize(FBitmap, FWidth - 10, FHeight - 10);
				
				FScaledSize.x = FBitmap.width;
				FScaledSize.y = FBitmap.height;
					
				FBitmap.x = (FWidth - FBitmap.width) / 2;
				//FBitmap.y = (FHeight - FBitmap.height) / 2;
				FBitmap.y = 0;
				
				FFullsize = false;
			}			
		}
		
		private function FullSize()
		{
			if (FBitmap)
			{
				FBitmap.width = FOriginalSize.x;
				FBitmap.height = FOriginalSize.y;
				FBitmap.x = 5;
				FBitmap.y = 5;
				FFullsize = true;
			}
		}
		
		public function Close()
		{
			visible = false;
			if (FBitmap)
			{
				FBitmap.bitmapData.dispose();
				removeChild(FBitmap);
				FBitmap = null;
			}
		}
		
		private function set Rotation(ARotation:int):void		
		{
			if (FBitmap)
			{
				var vMatrix:Matrix = FBitmap.transform.matrix;
				var vPoint:Point = new Point(FBitmap.x + FBitmap.width / 2, FBitmap.y + FBitmap.height / 2);				
				vMatrix.translate( -vPoint.x, -vPoint.y);
				vMatrix.rotate(ARotation * (Math.PI/180));			
				vMatrix.translate(vPoint.x, vPoint.y);
				FBitmap.transform.matrix = vMatrix;
			}
		}		
		
		public function Resize(AWidth:Number, AHeight:Number):void
		{
			FWidth = AWidth;
			FHeight = AHeight;
			FWidth < FHeight ? FMaxSize = FWidth : FMaxSize = FHeight;
			
			graphics.clear();
			graphics.beginFill(0, 0.5);
			graphics.drawRect(0, 0, FWidth, FHeight);
			graphics.endFill();
			
			FPreloader.x = (FWidth - FPreloader.width) / 2;
			FPreloader.y = (FHeight - FPreloader.height) / 2;
			
			if (FBitmap)
			{
				Rotation = -FRotation;
				FBitmap.width = FOriginalSize.x;
				FBitmap.height = FOriginalSize.y;
				FitToScreen();
				Rotation = FRotation;
			}			
		}		
	}
}